﻿/* 
 *========================================================================
 * 描述信息 
 *  
 * 作者：w       
 * 时间：2021/4/29 14:45:48 
 * 文件名：MsgQueueCustomer 
 * CLRVersion：4.0.30319.42000
 * 版本：V1.0.0 
 * 
 * 修改者：           
 * 时间：               
 * 修改说明： 
 *======================================================================== 
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.IO;

namespace ConsoleApplication2
{
    public class MsgQueueCustomer
    {
        /// <summary>
        /// 间隔，毫秒
        /// </summary>
        public const int INTERVAL = 1000;
        private static Dictionary<ushort, int> _dic;
        static MsgQueueCustomer()
        {
            _dic = new Dictionary<ushort, int>();
        }
        public static void Statistic()
        {
            while (true)
            {
                Tuple<ushort, MsgEntity> info = null;
                long now = DateTime.Now.Ticks;
                KeyValuePair<ushort, int> lasted = new KeyValuePair<ushort, int>();
                _dic.Clear();
                if (lasted.Key > 0)
                {
                    _dic.Add(lasted.Key, lasted.Value);
                }
                while (true)
                {
                    if (NetCapture.ThisQueue.Count > 0 && NetCapture.ThisQueue.TryDequeue(out info))
                    {
                        long infoTicks = info.Item2.RecevieTime;
                        if (infoTicks - now > INTERVAL * 10000)
                        {
                            lasted = new KeyValuePair<ushort, int>(info.Item1, info.Item2.DataLength);
                            break;
                        }
                        if (_dic.ContainsKey(info.Item1))
                        {
                            _dic[info.Item1] = _dic[info.Item1] + info.Item2.DataLength;
                        }
                        else
                        {
                            _dic.Add(info.Item1, info.Item2.DataLength);
                        }
                    }
                    else
                    {
                        Thread.Sleep(1);
                        if (DateTime.Now.Ticks - now > INTERVAL * 10000)
                        {
                            break;
                        }
                    }
                }
                DoOuputStatisticInfo();
            }
        }

        private static void DoOuputStatisticInfo()
        {
            if (_dic.Count == 0)
            {
                return;
            }
            List<MIB_TCPROW_OWNER_PID> pids = ExternCPlus.GetAllTCPConnections();
            Dictionary<uint, ProcessEntity> dic = new Dictionary<uint, ProcessEntity>();
            foreach (var item in pids)
            {
                if (dic.ContainsKey(item.ProcessId))
                {
                    dic[item.ProcessId].Ports.Add(item.LocalPort);
                }
                else
                {
                    dic.Add(item.ProcessId, new ProcessEntity() { ProcessID = item.ProcessId, Ports = new int[] { item.LocalPort }.ToList() });
                }
            }
            GetProcessName(dic);

            foreach (var item in _dic)
            {
                KeyValuePair<uint, ProcessEntity> kv = dic.FirstOrDefault(itm => itm.Value.Ports.Contains(item.Key));
                if (kv.Value != null)
                {
                    kv.Value.NetSpeed += item.Value;
                }
            }

            Console.WriteLine("======================================================================");
            Console.WriteLine("合计："+dic.Sum(itm => itm.Value.NetSpeed / INTERVAL) + "kb/s");
            foreach (var item in dic)
            {
                WriteOut(item.Value);
            }
        }

        private static void GetProcessName(Dictionary<uint, ProcessEntity> dic)
        {
            foreach (var item in dic)
            {
                try
                {
                    Process p = Process.GetProcessById((int)item.Value.ProcessID);
                    if (p != null)
                    {
                        string filename = p.MainModule.FileName;
                        FileInfo file = new FileInfo(filename);
                        item.Value.ProcessName = file.Name;
                    }
                }
                catch { }
            }
        }

        static void WriteOut(ProcessEntity process)
        {
            //&& process.ProcessName.Contains("BaiduNet")
            if (!string.IsNullOrEmpty(process.ProcessName))
            {
                Console.WriteLine(string.Format("{2}:进程名称={0}的端口={3}网速={1}kb/s", process.ProcessName,
                    process.NetSpeed / INTERVAL,
                    DateTime.Now.ToString("HH:mm:ss fff"),
                    string.Join(",", process.Ports.ToArray())));
            }
        }
    }

    public class ProcessEntity
    {
        public uint ProcessID { get; set; }
        public string ProcessName { get; set; }
        public List<int> Ports { get; set; }
        public double NetSpeed { get; set; }
    }
}
